#pragma once

#include"hashtable.h"

namespace bit
{

	template<class k, class Hash = Hashfunc<k>>
	class unordered_set
	{
		struct SetKeyofT
		{
			const k& operator()(const k& key)
			{
				return key;
			}
		};

	public:
		typedef typename HashTable<k, const k, SetKeyofT, Hash>::Iterator iterator;
		typedef typename HashTable<k, const k, SetKeyofT, Hash>::ConstIterator const_iterator;

		iterator begin()
		{
			return _t.Begin();
		}		
		
		const_iterator begin()const
		{
			return _t.Begin();
		}

		iterator end()
		{
			return _t.End();
		}		
		
		const_iterator end()const
		{
			return _t.End();
		}

		pair<iterator, bool> insert(const k& key)
		{
			return _t.Insert(key);
		}

		iterator find(const k& key)
		{
			_t.Find(key);
		}

		bool erase(const k& key)
		{
			return _t.Erase(key);
		}


	private:
		HashTable<k, const k, SetKeyofT, Hash> _t;
	};

	struct Date
	{
		int _year = 0;
		int _month = 0;
		int _day = 0;
		Date(int year, int month, int day)
			:_year(year)
			,_month(month)
			,_day(day)
		{ }
	};

	struct HashDate
	{
		size_t operator()(const Date& d)
		{
			return ((d._year + d._month) * 31 + d._day) * 31;
		}
	};


	//void Print(const unordered_set<int>& s)
	//{
	//	unordered_set<int>::const_iterator it = s.begin();
	//	while (it != s.end())
	//	{
	//		// *it += 1;
	//		cout << *it << " ";
	//		++it;
	//	}
	//	cout << endl;
	//}


	void test_set()
	{
		unordered_set<int> s;
		int a[] = { 4, 2, 6, 1, 3, 5, 15, 7, 16, 14, 3,3,15 };
		for (auto e : a)
		{
			s.insert(e);
		}

		for (auto e : s)
		{
			cout << e << " ";
		}
		cout << endl;

		//cout << typeid(s.end()).name() << endl;

		unordered_set<int>::iterator it = s.begin();
		while (it != s.end())
		{
			//*it += 1;

			cout << *it << " ";
			++it;
		}
		cout << endl;

		unordered_set<Date, HashDate> us;
		us.insert({ 2024, 7, 25 });
		us.insert({ 2024, 7, 26 });

		//Print(s);
	}


}
